<template>
  <n-grid :cols="cols || 24" :x-gap="xGap ?? cols ?? 24" :y-gap="yGap">
    <n-form-item-gi
      v-for="item in items"
      :key="item.key"
      :span="item.span ?? cols ?? 24"
      :label="item.label"
      :path="item.key"
      :feedback-class="feedbackClass"
      :feedback-style="feedbackStyle">
      <component :is="asyncComp(item.type)" v-model="form[item.key]" :option="item" />
    </n-form-item-gi>
  </n-grid>
</template>

<script lang="ts" setup>
import { defineAsyncComponent, type CSSProperties, type Component } from "vue";
import { NGrid, NFormItemGi } from "naive-ui";
import type { RowData } from "@/_interface";
import type { NaiveFormItem } from "./interface";

const form = defineModel<RowData>({ required: true });

defineProps<{
  cols?: number;
  xGap?: number;
  yGap?: number;
  feedbackClass?: string;
  feedbackStyle?: string | CSSProperties;
  items?: NaiveFormItem<any>[];
}>();

const componentCache: Record<string, Component> = {};
const asyncComp = (formType?: string) => {
  formType = formType || "input";
  if (["select", "textarea"].includes(formType)) formType = "input";

  if (componentCache[formType]) return componentCache[formType];

  const compType = formType.charAt(0).toUpperCase() + formType.slice(1);
  const loadedComp = defineAsyncComponent(() => import(`./form-items/${compType}.vue`));
  componentCache[formType] = loadedComp;
  return loadedComp;
};
</script>
